using System.Diagnostics;
using Klear.Library.Models;

namespace Klear.Library.Services;

public class RemindStorage : IRemindStorage
{
    private readonly IBudgetService _budgetService;
    private readonly IDatabaseService _databaseService;
    private BudgetModel _currentBudget;
    private bool _isSaving;
    private bool _isDeleting;
    
    // 定义预算警告事件
    public event EventHandler<BudgetWarningEventArgs> BudgetWarningTriggered;
    
    public RemindStorage(IBudgetService budgetService,
        IDatabaseService databaseService)
    {
        _budgetService = budgetService;
        _databaseService = databaseService;
        
        // 订阅支出添加事件
        _databaseService.ExpenseAdded += OnExpenseAdded;
        _databaseService.ExpenseDeleted += OnExpenseDeleted;
    }
    
    public async Task Initialize()
    {
        _currentBudget = await _budgetService.GetCurrentMonthBudgetAsync();
        await CheckBudgetWarning();
    }
    
    // 处理支出添加事件
    private async void OnExpenseAdded(object sender, IncomeAndExpensesModel expense)
    {
        await CheckBudgetWarning();
    }
    
    // 处理支出删除事件
    private async void OnExpenseDeleted(object sender, IncomeAndExpensesModel expense)
    {
        _isDeleting = true;
        try
        {
            await CheckBudgetWarning();
        }
        finally
        {
            _isDeleting = false;
        }
    }
    
    public async Task CheckBudgetWarning()
    {
        if (_currentBudget == null) return;
        
        try 
        {
            var actualSpending = await _budgetService.CalculateActualSpending(
                _currentBudget.StartDate, 
                _currentBudget.EndDate);
            
            // 添加日志输出来调试
            Debug.WriteLine($"Checking budget warning: Actual={actualSpending:C2}, Threshold={_currentBudget.WarningThreshold:C2}");
                
            if (actualSpending > _currentBudget.WarningThreshold)
            {
                OnBudgetWarningTriggered(new BudgetWarningEventArgs(
                    actualSpending,
                    _currentBudget.WarningThreshold,
                    _currentBudget.Budget
                ));
                
                // 添加日志输出来调试
                Debug.WriteLine("Budget warning triggered!");
            }
            else
            {
                // 如果支出低于阈值，发送一个特殊的事件来清除警告
                OnBudgetWarningTriggered(new BudgetWarningEventArgs(
                    actualSpending,
                    _currentBudget.WarningThreshold,
                    _currentBudget.Budget
                ));
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"Error in CheckBudgetWarning: {ex}");
            throw;
        }
    }
    
    // 更新当前预算设置
    public async Task UpdateBudget(BudgetModel newBudget)
    {
        _isSaving = true;
        try 
        {
            _currentBudget = newBudget;
            await _budgetService.SaveBudgetSettings(newBudget);
            await CheckBudgetWarning();
        }
        finally
        {
            _isSaving = false;
        }
    }
    
    public async Task<BudgetModel> GetCurrentBudget()
    {
        if (_currentBudget == null)
        {
            _currentBudget = await _budgetService.GetCurrentMonthBudgetAsync();
        }
        return _currentBudget;
    }
    
    protected virtual void OnBudgetWarningTriggered(BudgetWarningEventArgs e)
    {
        if (!_isSaving && !_isDeleting ) // 只在非保存和非删除操作时触发警告
        {
            BudgetWarningTriggered?.Invoke(this, e);
        }
        // 在删除操作后，也需要更新警告状态
        else if (_isDeleting)
        {
            // 使用相同的事件来更新UI状态，但不显示弹窗
            BudgetWarningTriggered?.Invoke(this, e);
        }
    }
    
    public void Cleanup()
    {
        // 取消订阅事件
        _databaseService.ExpenseAdded -= OnExpenseAdded;
        _databaseService.ExpenseDeleted -= OnExpenseDeleted;
    }
}

public class BudgetWarningEventArgs : EventArgs
{
    public decimal ActualSpending { get; }
    public decimal WarningThreshold { get; }
    public decimal TotalBudget { get; }
    
    public BudgetWarningEventArgs(decimal actualSpending, decimal warningThreshold, decimal totalBudget)
    {
        ActualSpending = actualSpending;
        WarningThreshold = warningThreshold;
        TotalBudget = totalBudget;
    }
}